没有 Docker,可以有 Linux 容器吗?没有 OpenShift,可以有 Linux 容器吗?没有 Kubernetes,可以有 Linux 容器吗?
答案是肯定的。早在 Docker 让容器成为家喻户晓的术语(如果您身处数据中心,情况确实如此)的数年前,LXC 项目就开发了运行一种虚拟操作系统的概念,它共享相同的内核,但包含在定义的进程组中。
Docker 构建于 LXC 之上,如今,有许多平台直接或间接地利用了 LXC 的工作成果。大多数这些平台都使创建和维护容器变得极其简单,对于大型部署而言,使用此类专用服务是有意义的。然而,并非每个人都在管理大型部署,或者能够访问大型服务来学习容器化。好消息是,您只需一台运行 Linux 的 PC 和本文,就可以创建、使用和学习容器。本文将通过研究 LXC,探讨其工作原理、工作原因以及在出现问题时如何进行故障排除,帮助您理解容器。
绕过简易性
如果您正在寻找 LXC 的快速入门指南,请参阅优秀的 Linux 容器 网站。
安装 LXC
如果尚未安装,您可以使用您的软件包管理器安装 LXC。
在 Fedora 或类似系统上,输入
$ sudo dnf install lxc lxc-templates lxc-doc
在 Debian、Ubuntu 和类似系统上,输入
$ sudo apt install lxc
创建网络桥接
大多数容器都假定网络可用,而大多数容器工具都期望用户能够创建虚拟网络设备。容器所需的最基本单元是网络桥接,它或多或少是网络交换机的软件等效物。网络交换机有点像智能 Y 型适配器,用于拆分耳机插孔,以便两个人可以使用单独的耳机听到相同的内容,只不过网络交换机桥接的是网络数据,而不是音频信号。
您可以创建自己的软件网络桥接,以便您的主机和容器操作系统都可以通过单个网络设备(以太网端口或无线网卡)发送和接收不同的网络数据。这是一个重要的概念,一旦您从手动生成容器毕业,通常会被忽略,因为无论您的部署规模有多大,您都不太可能为运行的每个容器配备专用的物理网卡。理解容器与虚拟网络设备通信至关重要,这样您就知道在容器失去网络连接时从哪里开始进行故障排除。
要在您的机器上创建网络桥接,您必须具有相应的权限。对于本文,请使用 sudo 命令以 root 权限操作。(但是,LXC 文档提供了在不使用 sudo 的情况下授予用户执行此操作的权限的配置。)
$ sudo ip link add br0 type bridge
验证是否已创建虚拟网络接口
$ sudo ip addr show br0
7: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc
noop state DOWN group default qlen 1000
link/ether 26:fa:21:5f:cf:99 brd ff:ff:ff:ff:ff:ff
由于 br0 被视为网络接口,因此它需要自己的 IP 地址。选择一个有效的本地 IP 地址,该地址不与网络上的任何现有 IP 地址冲突,并将它分配给 br0 设备
$ sudo ip addr add 192.168.168.168 dev br0
最后,确保 br0 正在运行
$ sudo ip link set br0 up
设置容器配置
LXC 容器的配置文件可以根据需要变得复杂,以定义容器在您的网络和主机系统中的位置,但对于此示例,配置很简单。在您喜欢的文本编辑器中创建一个文件,并定义容器的名称和网络所需的设置
lxc.utsname = opensourcedotcom
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 4a:49:43:49:79:bd
lxc.network.ipv4 = 192.168.168.1/24
lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596
将此文件保存在您的主目录中,命名为 mycontainer.conf。
lxc.utsname 是任意的。您可以随意命名您的容器;这是您在启动和停止容器时将使用的名称。
网络类型设置为 veth,这是一种虚拟以太网跳线。其理念是 veth 连接从容器连接到桥接设备,桥接设备由 lxc.network.link 属性定义,设置为 br0。容器的 IP 地址与桥接设备在同一网络中,但必须是唯一的,以避免冲突。
除了 veth 网络类型和 up 网络标志之外,配置文件中的所有值都是您自己发明的。属性列表可从 man lxc.container.conf 中获得。(如果您的系统上缺少该列表,请在您的软件包管理器中查找单独的 LXC 文档包。)在 /usr/share/doc/lxc/examples 中有几个示例配置文件,您稍后应该查看它们。
启动容器 shell
此时,您已经完成了可操作容器的三分之二:您拥有网络基础设施,并且您已经在虚拟 PC 中安装了虚拟网卡。现在您只需要安装操作系统。
然而,即使在这个阶段,您也可以通过在容器空间内启动 shell 来查看 LXC 的工作原理。
$ sudo lxc-execute --name basic \
--rcfile ~/mycontainer.conf /bin/bash \
--logfile mycontainer.log
#
在这个非常简陋的容器中,查看您的网络配置。它应该看起来既熟悉又独特。
# /usr/sbin/ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state [...]
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
[...]
22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> [...] qlen 1000
link/ether 4a:49:43:49:79:bd brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.168.167/24 brd 192.168.168.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 2003:db8:1:0:214:1234:fe0b:3596/64 scope global
valid_lft forever preferred_lft forever
[...]
您的容器知道其伪造的网络基础设施和熟悉而独特的内核。
# uname -av
Linux opensourcedotcom 4.18.13-100.fc27.x86_64 #1 SMP Wed Oct 10 18:34:01 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
使用 exit 命令退出容器
# exit
安装容器操作系统
构建完整的容器化环境比网络和配置步骤复杂得多,因此您可以从 LXC 借用容器模板。如果您没有任何模板,请在您的软件仓库中查找单独的 LXC 模板包。
默认的 LXC 模板位于 /usr/share/lxc/templates 中。
$ ls -m /usr/share/lxc/templates/
lxc-alpine, lxc-altlinux, lxc-archlinux, lxc-busybox, lxc-centos, lxc-cirros, lxc-debian, lxc-download, lxc-fedora, lxc-gentoo, lxc-openmandriva, lxc-opensuse, lxc-oracle, lxc-plamo, lxc-slackware, lxc-sparclinux, lxc-sshd, lxc-ubuntu, lxc-ubuntu-cloud
选择您喜欢的模板,然后创建容器。此示例使用 Slackware。
$ sudo lxc-create --name slackware --template slackware
观看模板的执行过程几乎与从头开始构建模板一样具有教育意义;它非常详细,您可以看到 lxc-create 将容器的“根”设置为 /var/lib/lxc/slackware/rootfs,并且正在将多个软件包下载并安装到该目录中。
通读模板文件可以让您更好地了解其中涉及的内容:LXC 设置了最小的设备树、常用 spool 文件、文件系统表 (fstab)、init 文件等等。它还阻止了一些在容器中没有意义的服务(例如用于硬件检测的 udev)启动。由于模板涵盖了广泛的典型 Linux 配置,如果您打算设计自己的模板,明智的做法是将您的工作基于最接近您想要设置的模板;否则,您肯定会犯遗漏错误(如果不是其他错误),而 LXC 项目已经遇到并解决了这些错误。
安装了最小的操作系统环境后,您可以启动您的容器。
$ sudo lxc-start --name slackware \
--rcfile ~/mycontainer.conf
您已启动容器,但尚未连接到它。(与之前的基本示例不同,这次您不仅是运行 shell,而是运行容器化的操作系统。)通过名称连接到它。
$ sudo lxc-attach --name slackware
#
检查您的环境的 IP 地址是否与您的配置文件中的地址匹配。
# /usr/sbin/ip addr show | grep eth
34: eth0@if35: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 [...] 1000
link/ether 4a:49:43:49:79:bd brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.168.167/24 brd 192.168.168.255 scope global eth0
退出容器,并将其关闭。
# exit
$ sudo lxc-stop slackware
使用 LXC 运行真实世界的容器
在现实生活中,LXC 可以轻松创建和运行安全可靠的容器。自 2008 年 LXC 推出以来,容器已经取得了长足的进步,因此请充分利用其开发人员的专业知识。
虽然 linuxcontainers.org 上的 LXC 说明使该过程变得简单,但手动方面的这次巡览应该有助于您了解幕后发生的事情。
1 条评论